package common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class WorkingBethaNode extends WorkingMemory{
	private BethaNode parentBethaNode;
	private List<BethaNode> childBethaNodes;
	private List<Node> rightHandSide;
	private Map<String, String> values;
	
	static int cont = 0;
	private int id;
	
	public WorkingBethaNode(){
		childBethaNodes = new ArrayList<BethaNode>();
		rightHandSide = new ArrayList<Node>();
		values = new HashMap<String, String>();
		id = cont++;
	}
	public BethaNode getParentBethaNode() {
		return parentBethaNode;
	}
	public void setParentBethaNode(BethaNode parentBethaNode) {
		this.parentBethaNode = parentBethaNode;
	}
	public List<BethaNode> getChildBethaNodes() {
		return childBethaNodes;
	}
	public void setChildBethaNodes(List<BethaNode> childBethaNodes) {
		this.childBethaNodes = childBethaNodes;
	}
	public void addBethaNode(BethaNode betha){
		betha.getWorkingParentBethaNodes().add(this);
		this.childBethaNodes.add(betha);
	}
	public String toString(){
		String aux = "(WorkingBethaNode_"+id+")";
		if(childBethaNodes.isEmpty()){
			aux += " [[Es hoja]]  ===>  ";
			for(Node nodo : rightHandSide){
				aux += nodo.toString() + ", ";
			}
		}
		else
		{
			for (BethaNode betha : childBethaNodes)
			{
				aux += "\n\t\t\t\t" + betha.toString2();
			}
		}
		aux+="\n\t\t";
		return aux;
	}
	public List<Node> getRightHandSide() {
		return rightHandSide;
	}
	public void setRightHandSide(List<Node> rightHandSide) {
		this.rightHandSide = rightHandSide;
	}
	
	public void addRHS(Node rhs){
		rightHandSide.add(rhs);
	}
	
	public List<Node> updateState(Map<String, String> vals){
		values.putAll(vals);
		return checkConditions();
	}
	
	public List<Node> checkConditions(){
		if(!values.isEmpty() && isLeaf())
			return rightHandSide;
		else {
			Set<String> keySet = values.keySet();
			List<Node> listRHS = new ArrayList<Node>();
			for(BethaNode betha : childBethaNodes){				
				for(String key : keySet){
					List<Node> aux = betha.updateState(key, values.get(key));
					if(aux != null)
						listRHS.addAll(aux);
				}
			}
			if(listRHS.isEmpty())
				return null;
			else
				return listRHS;
		}
	}
	
	public boolean isLeaf(){
		return childBethaNodes.isEmpty();
	}
	
	public int getTotalValuesExpected(){
		return parentBethaNode.getTotalValuesExpected();
	}

}
